package com.piece.admin.controller.system;

import com.piece.admin.model.TbSysRole;
import com.piece.admin.service.TbSysRoleService;
import com.piece.admin.support.TranslateEntity;
import com.piece.core.framework.annotation.permission.AclPermission;
import com.piece.core.framework.annotation.permission.SubmitPermission;
import com.piece.core.framework.constant.ExceptionConstants;
import com.piece.core.framework.constant.FrameWorkConstants;
import com.piece.core.framework.support.bootstrap.DataTable;
import com.piece.core.framework.support.bootstrap.QueryTable;
import com.piece.core.framework.support.bootstrap.TreeData;
import com.piece.core.framework.support.convert.Convert;
import com.piece.core.framework.support.response.AjaxResponse;
import com.piece.core.framework.util.object.ClassUtil;
import com.piece.core.framework.util.basic.I18nUtil;
import com.piece.core.framework.util.object.ObjectUtil;
import com.piece.core.framework.util.string.StringUtil;
import com.piece.core.log.client.dto.UserDTO;
import com.piece.core.log.config.UserContextHolder;
import com.piece.core.web.controller.FrameWorkController;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.*;

@Api(tags = {"角色管理"})
@RestController
@RequestMapping("/api/system/role")
public class SysRoleController extends FrameWorkController {

    @Autowired
    protected TranslateEntity translateEntity;

    @Resource
    private TbSysRoleService tbSysRoleService;

    @PostMapping("/list")
    @AclPermission(code = "system:role:view")
    @ApiOperation(value = "查询角色列表")
    @ApiImplicitParam(value = "查询条件", dataTypeClass = QueryTable.class, type = "body")
    public List list() {
        QueryTable queryTable = initTable();
        DataTable dataTable = tbSysRoleService.findPage(queryTable);
        return dataTable.getData();
    }

    @PostMapping("/table")
    @AclPermission(code = "system:role:view")
    @ApiOperation(value = "查询角色分页数据")
    @ApiImplicitParam(value = "查询条件", dataTypeClass = QueryTable.class, type = "body")
    public AjaxResponse table() {
        QueryTable queryTable = initTable();
        DataTable dataTable = tbSysRoleService.findPage(queryTable);
        return success(dataTable);
    }

    @GetMapping("/load")
    @AclPermission(code = "system:role:view")
    @ApiOperation(value = "生成角色表单数据")
    @ApiImplicitParam(name = "id", value = "主键")
    public AjaxResponse load() {
        long id = Convert.toLong(getRequest().getParameter("id"), 0L);
        TbSysRole role = new TbSysRole();
        if (id != 0) {
            role = tbSysRoleService.findById(id);
            translateEntity.setEntityInfo(role);
        }
        return success(role);
    }

    @SubmitPermission
    @PostMapping("/save")
    @AclPermission(code = "system:role:add,system:role:edit")
    @ApiOperation(value = "保存角色表单数据")
    @ApiImplicitParam(value = "表单数据", dataTypeClass = TbSysRole.class, type = "body")
    public AjaxResponse save() {
        TbSysRole role;
        try {
            Long id = Convert.toLong(getRequest().getParameter("roleId"));
            if (null != id) {
                role = tbSysRoleService.findById(id);
            } else {
                role = new TbSysRole();
            }
            initDB(role);
            if (ClassUtil.isEmpty(id)) {
                setDefaultInfo(role, true);
            } else {
                setDefaultInfo(role, false);
            }
            tbSysRoleService.insertOrUpdate(role);
            return success(I18nUtil.message(ExceptionConstants.SAVE_SUCCESS), null);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE), e.getMessage());
        }
    }

    @SubmitPermission
    @PostMapping("/saveDataScope")
    @AclPermission(code = "system:role:grant")
    @ApiOperation(value = "保存角色数据权限")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID"),
            @ApiImplicitParam(name = "dataScope", value = "数据范围"),
            @ApiImplicitParam(name = "deptIds", value = "部门ID集合")
    })
    public AjaxResponse saveDataScope() {
        try {
            Long id = Convert.toLong(getRequest().getParameter("roleId"));
            if (ClassUtil.isEmpty(id)) {
                return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE));
            } else {
                String dataScope = getRequest().getParameter("dataScope");
                String deptIds = getRequest().getParameter("deptIds");
                TbSysRole role = tbSysRoleService.findById(id);
                role.setDataScope(dataScope);
                role.setDeptIds(deptIds);
                setDefaultInfo(role, false);
                tbSysRoleService.updateRoleDept(role);
            }
            return success(I18nUtil.message(ExceptionConstants.SAVE_SUCCESS), null);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE), e.getMessage());
        }
    }

    @SubmitPermission
    @PostMapping("/saveRoleMenu")
    @AclPermission(code = "system:role:grant")
    @ApiOperation(value = "保存角色菜单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID"),
            @ApiImplicitParam(name = "menuIds", value = "菜单ID集合")
    })
    public AjaxResponse saveRoleMenu() {
        try {
            Long id = Convert.toLong(getRequest().getParameter("roleId"));
            if (ClassUtil.isEmpty(id)) {
                return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE));
            } else {
                String menuIds = getRequest().getParameter("menuIds");
                TbSysRole role = tbSysRoleService.findById(id);
                role.setMenuIds(menuIds);
                setDefaultInfo(role, false);
                tbSysRoleService.updateRoleMenu(role);
            }
            return success(I18nUtil.message(ExceptionConstants.SAVE_SUCCESS), null);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE), e.getMessage());
        }
    }

    @SubmitPermission
    @PostMapping("/addRoleUser")
    @AclPermission(code = "system:role:grant")
    @ApiOperation(value = "添加角色用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID集合"),
            @ApiImplicitParam(name = "userIds", value = "用户ID集合", dataTypeClass = String[].class)
    })
    public AjaxResponse addRoleUser() {
        try {
            Long id = Convert.toLong(getRequest().getParameter("roleId"));
            String[] userIds = getRequest().getParameterValues("userIds");
            if (ClassUtil.isEmpty(id)) {
                return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE));
            } else if (ObjectUtil.isNotEmpty(userIds)) {
                TbSysRole role = tbSysRoleService.findById(id);
                role.setUserIds(StringUtil.joinWith(FrameWorkConstants.SPLIT_PARAM, userIds));
                tbSysRoleService.insertRoleUser(role);
            }
            return success(I18nUtil.message(ExceptionConstants.SAVE_SUCCESS), null);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE), e.getMessage());
        }
    }

    @SubmitPermission
    @PostMapping("/updateRoleUser")
    @AclPermission(code = "system:role:edit")
    @ApiOperation(value = "更新角色用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID"),
            @ApiImplicitParam(name = "userIds", value = "用户ID集合", dataTypeClass = String[].class)
    })
    public AjaxResponse updateRoleUser() {
        try {
            Long id = Convert.toLong(getRequest().getParameter("roleId"));
            if (ClassUtil.isEmpty(id)) {
                return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE));
            } else {
                String[] userIds = getRequest().getParameterValues("userIds");
                TbSysRole role = tbSysRoleService.findById(id);
                role.setUserIds(StringUtil.joinWith(FrameWorkConstants.SPLIT_PARAM, userIds));
                setDefaultInfo(role, false);
                tbSysRoleService.updateRoleUser(role);
            }
            return success(I18nUtil.message(ExceptionConstants.SAVE_SUCCESS), null);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.SAVE_FAILURE), e.getMessage());
        }
    }

    @SubmitPermission
    @PostMapping("/delete")
    @AclPermission(code = "system:role:delete")
    @ApiOperation(value = "删除角色")
    @ApiImplicitParam(name = "ids", value = "角色ID集合")
    public AjaxResponse delete() {
        String ids = getRequest().getParameter("ids");
        if (StringUtil.isNotEmpty(ids)) {
            tbSysRoleService.delete(Convert.toLongArray(ids));
        }
        return success(I18nUtil.message(ExceptionConstants.DELETE_SUCCESS), null);
    }

    @SubmitPermission
    @PostMapping("/deleteRoleUser")
    @AclPermission(code = "system:role:grant")
    @ApiOperation(value = "删除角色用户")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "roleId", value = "角色ID"),
            @ApiImplicitParam(name = "userIds", value = "用户ID集合", dataTypeClass = String[].class)
    })
    public AjaxResponse deleteRoleUser() {
        try {
            Long id = Convert.toLong(getRequest().getParameter("roleId"));
            String[] userIds = Convert.toStrArray(FrameWorkConstants.SPLIT_PARAM, getRequest().getParameter("userIds"));
            if (ObjectUtil.isNotEmpty(userIds)) {
                tbSysRoleService.deleteRoleUserByRoleId(id, StringUtil.joinWith(FrameWorkConstants.SPLIT_PARAM, userIds));
            }
            return success(I18nUtil.message(ExceptionConstants.DELETE_SUCCESS), null);
        } catch (Exception e) {
            return error(I18nUtil.message(ExceptionConstants.DELETE_FAILURE), e.getMessage());
        }
    }

    /**
     * 加载所有菜单列表树
     */
    @PostMapping("/treeData")
    @AclPermission(code = "system:role:view")
    @ApiOperation(value = "加载所有角色列表树数据")
    @ApiImplicitParam(name = "selected", value = "已选角色ID")
    public List<TreeData> treeData() {
        String selected = getRequest().getParameter("selected");
        List<String> checkedList = new ArrayList<>();
        List<TbSysRole> roleList = tbSysRoleService.findAll();
        if (StringUtil.isNotEmpty(selected)) {
            checkedList = Arrays.asList(Convert.toStrArray(selected));
        }
        return tbSysRoleService.findTreeData(roleList, true, checkedList);
    }

    @GetMapping("/convertName")
    @ApiOperation(value = "根据角色ID加载角色名称")
    @ApiImplicitParam(name = "ids", value = "已选角色ID")
    public AjaxResponse convertName() {
        String ids = getRequest().getParameter("ids");
        if (StringUtil.isNotEmpty(ids)) {
            return success(tbSysRoleService.convertIdToName(ids));
        }
        return success();
    }

    private void setDefaultInfo(TbSysRole role, boolean insert) {
        UserDTO user = UserContextHolder.get();
        if (insert) {
            role.setCreateBy(user.getId());
            role.setCreateTime(new Date());
        }
        role.setUpdateBy(user.getId());
        role.setUpdateTime(new Date());
    }
}
